home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / dos / secmpeg3 / header.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  8.6 KB  |  450 lines

  1.  
  2. /* --- C ---
  3. ************************************************************************
  4. *
  5. *    Filename    : header.c
  6. *    Description : Analysation of MPEG-Headers
  7. *    Part of     : SECMPEG
  8. *
  9. *    Version     : 1.0
  10. *    Language    : C
  11. *    For machine : SunOS 4.1.x, INTERACTIVE Unix 2.2.1, Linux, MS-DOS
  12. *    Compile as  : see Makefile
  13. *
  14. *    Authors     : Juergen Meyer, Frank Gadegast
  15. *    Contact     : jm@cs.tu-berlin.de, phade@cs.tu-berlin.de
  16. *
  17. ************************************************************************
  18. */
  19.  
  20. #include <stdio.h>
  21. #include "defs.h"
  22. #include "marker.h"
  23. #include "header.h"
  24. #include "qtables.h"
  25.  
  26. /* ------ PUBLIC ------ */
  27.  
  28. int    ReadHeader(void);              /*   !!!!!!!!!!!!!!!      */
  29. void   ReadHeaderTrailor();           /* alle Funktionen        */
  30. int    ClearToHeader();               /* operieren auf dem      */
  31. int    ReadVideoSequenceHeader();     /* FrameBuffer, d.h. keine*/
  32. void   ReadGroupOfPicturesHeader();   /* direkte io-operationen */
  33.                       
  34. int    ReadPictureHeader();
  35. void   ReadSliceHeader();
  36. int    ReadMakroblockHeader();
  37.  
  38.  
  39.  
  40. /* ------ PRIVAT ------ */
  41.  
  42. static INT DecodeMV(INT,INT);
  43.  
  44. /* ------ IMPORT ------ */
  45.  
  46. extern void    readalign();
  47. extern int     CheckEOF();
  48.  
  49. extern int     GetnBit(int);         /* decode.c */
  50. extern int     GetBit();
  51. extern void    bytealign();
  52.  
  53.  
  54.  
  55. extern INT     Decode(DHUFF *);      /* huff.c */
  56.  
  57. extern long total_bytes_read;        /* stream.c */
  58. extern INT bit_set_mask[];
  59.  
  60. extern INT csize[];                  /* huff.h */
  61. extern DHUFF *MBADHuff;
  62. extern DHUFF *MVDDHuff;
  63. extern DHUFF *CBPDHuff;
  64. extern DHUFF *T1DHuff;
  65. extern DHUFF *T2DHuff;
  66. extern DHUFF *IntraDHuff;
  67. extern DHUFF *PredictedDHuff;
  68. extern DHUFF *InterpolatedDHuff;
  69. extern DHUFF *DCLumDHuff;
  70. extern DHUFF *DCChromDHuff;
  71. extern DHUFF **ModuloDHuff;
  72.  
  73. /* -------------------------------------------- */
  74.  
  75. int ReadHeader(void)
  76. {
  77.        INT  retval;
  78.  
  79. #ifdef DEBUG
  80.        fprintf(stderr,"ReadHeader\n");
  81. #endif
  82.  
  83.        readalign(); 
  84.        if ((retval = GetnBit(MBSC_LENGTH)) != MBSC)
  85.        {
  86.       while(!retval)
  87.       {
  88.          if ((retval = GetnBit(8)) == MBSC)
  89.         return(0);
  90.          else if(retval && (CheckEOF()))
  91.          {
  92. #ifdef DEBUG
  93.             fprintf(stderr," %s\n"," End of File ");
  94. #endif
  95.             error_exit(0);
  96.          }
  97.       }
  98. #ifdef DEBUG
  99.       fprintf(stderr,"Bad input read: %d\n",retval);
  100. #endif
  101.       return(-1);
  102.        }
  103.        return(0);
  104. }
  105.  
  106.  
  107.  
  108. void ReadHeaderTrailer()
  109. {
  110.  
  111.      INT  trailor_val;
  112.  
  113. #ifdef DEBUG
  114.        fprintf(stderr,"ReadHeaderTrailor\n");
  115. #endif
  116.  
  117.      while(TRUE)
  118.      {
  119.      trailor_val = GetnBit(8);
  120.      switch(trailor_val)
  121.      {
  122.      case  0:
  123.          MBSRead = -1;
  124.          return;
  125.      case GOPSC :
  126.          MBSRead = -2;
  127.          return;
  128.      case VSEC:
  129.          MBSRead = -3;
  130.          return;
  131.      case VSSC:
  132.          MBSRead = -4;
  133.          return;
  134.      case UDSC:
  135. #ifdef DEBUG
  136.             fprintf(stderr,"User data code found.\n");
  137. #endif
  138.             ClearToHeader();
  139.             break;
  140.  
  141.      case EXSC:
  142. #ifdef DEBUG
  143.             fprintf(stderr,"Extension data code found.\n");
  144. #endif
  145.             ClearToHeader();
  146.             break;
  147.  
  148.      default:   if ((trailor_val > 0) && (trailor_val < 0xb0))
  149.             {
  150.             MBSRead = trailor_val-1;
  151.             SVP = trailor_val;
  152.             }
  153.             return;
  154.     }
  155.     }
  156. }
  157.  
  158.  
  159.  
  160. int  ClearToHeader()
  161. {
  162.   
  163.   INT input;
  164.  
  165. #ifdef DEBUG
  166.   fprintf(stderr,"ClearToHeader\n");
  167. #endif
  168.  
  169.   readalign();               
  170.   if ((input = GetnBit(MBSC_LENGTH)) != MBSC)
  171.     {
  172.       do
  173.         {
  174.           if (CheckEOF())
  175.               error_exit(ERROR_PREMATURE_EOF);
  176.             
  177.           input = input & 0xffff;               
  178.       input = (input << 8) | GetnBit(8);
  179.         }
  180.       while (input != MBSC);  
  181.     }
  182.     return(0);
  183. }
  184.  
  185.  
  186.  
  187. int    ReadVideoSequenceHeader()
  188. {
  189.     INT i;
  190.  
  191. #ifdef DEBUG
  192.        fprintf(stderr,"ReadVideoSequenceHeader\n");
  193. #endif
  194.  
  195.     HorizontalSize = GetnBit(12);
  196.     VerticalSize   = GetnBit(12);
  197.     Aprat          = GetnBit(4);
  198.  
  199.     if ((!Aprat)||(Aprat==0xf))
  200.        return(ERROR_ASPECT_RATIO);
  201.     Prate = GetnBit(4);
  202.  
  203.     if ((!Prate) || (Prate > 8))
  204.        return(ERROR_PICTURE_RATE);
  205.  
  206.     Brate = GetnBit(18);
  207.     if (!Brate)
  208.        return(ERROR_BIT_RATE);
  209.     if (Brate == 0x3fff)
  210.         Rate=0;
  211.     else
  212.         Rate = Brate*400;
  213.  
  214.        (void) GetBit();
  215.  
  216.        Bsize      = GetnBit(10);
  217.        BufferSize = Bsize*16*1024;
  218.  
  219.        ConstrainedParameterFlag = GetBit();
  220.  
  221.        LoadIntraQuantizerMatrix = GetBit();
  222.  
  223.        if(LoadIntraQuantizerMatrix)
  224.       for( i = 0; i < BLOCKSIZE;i++)
  225.          MPEGIntraQ[i] = GetnBit(8);
  226.  
  227.        LoadNonIntraQuantizerMatrix = GetBit();
  228.        if(LoadNonIntraQuantizerMatrix)
  229.       for( i = 0; i < BLOCKSIZE;i++)
  230.          MPEGNonIntraQ[i] = GetnBit(8);
  231.  
  232.        return(0);
  233. }
  234.  
  235. void ReadGroupOfPicturesHeader()
  236. {
  237.  
  238. #ifdef DEBUG
  239.        fprintf(stderr,"%s : %d\n","ReadGroupOfPicturesHeader",groupofpictures_count++);
  240. #endif
  241.  
  242.   TimeCode   = GetnBit(25);
  243.   ClosedGOP  = GetBit();
  244.   BrokenLink = GetBit();
  245. }
  246.  
  247.  
  248.  
  249. /* -------------------------------------------------------- */
  250.  
  251. int ReadPictureHeader()
  252. {
  253.  
  254. #ifdef DEBUG
  255.        fprintf(stderr,"ReadPictureHeader\n");
  256. #endif
  257.   bytealign();
  258.   TemporalReference = GetnBit(10);
  259.   PType = GetnBit(3);
  260.  
  261.   if(!PType)
  262.       return(ERROR_FRAME_TYPE);
  263.  
  264.   BufferFullness = GetnBit(16);
  265.  
  266.   if ((PType == P_PREDICTED) || (PType == P_INTERPOLATED))
  267.     {
  268.       FullPelForward = GetBit();
  269.       ForwardIndex = GetnBit(3);
  270.     }
  271.   if (PType == P_INTERPOLATED)
  272.     {
  273.       FullPelBackward = GetBit();
  274.       BackwardIndex = GetnBit(3);
  275.     }
  276.   PictureExtra=0;
  277.   while(GetBit())
  278.     {
  279.       PictureExtraInfo = GetnBit(8);
  280.       PictureExtra = 1;
  281.     }
  282.  
  283.     return(PType);
  284. }
  285.  
  286. /* -------------------------------------------------------- */
  287.  
  288. void ReadSliceHeader()
  289. {
  290. #ifdef DEBUG
  291.        fprintf(stderr,"%s : %d\n","ReadSliceHeader",sliceheader_count++);
  292. #endif
  293.  
  294.   SQuant = GetnBit(5);
  295.   for(SliceExtra=0;GetBit();)
  296.     {
  297.       SliceExtraInfo = GetnBit(8);
  298.       SliceExtra = 1;
  299.     }
  300. }
  301.  
  302. int ReadMakroBlockHeader()
  303. {
  304.   INT Readin;
  305.  
  306. #ifdef DEBUG
  307.        fprintf(stderr,"%s : %d\n","ReadMakroBlockHeader",current_makroblock);
  308. #endif
  309.  
  310.   current_makroblock++;
  311.  
  312.   for(MBAIncrement=0;;)
  313.     {
  314.       do
  315.     {
  316.       Readin = Decode(MBADHuff);
  317.     }
  318.       while(Readin == 34);
  319.       if (Readin < 34)
  320.     {
  321.       MBAIncrement += Readin;
  322.       break;
  323.     }
  324.       else if (Readin == 36)
  325.     {
  326.       while(!GetBit());
  327.       return(-1);
  328.     }
  329.       else if (Readin == 35)
  330.     MBAIncrement += 33;
  331.       else
  332.     {
  333. #ifdef DEBUG
  334.       fprintf(stderr,"Bad MBA Read: %d \n",Readin);
  335. #endif
  336.       fprintf(stderr,"Bad MBA Read: %d \n",Readin);
  337.  
  338.       break;
  339.     }
  340.     }
  341.   switch(PType)
  342.     {
  343.     case P_INTRA:
  344.       MType = Decode(IntraDHuff);
  345.       break;
  346.     case P_PREDICTED:
  347.       if (MBAIncrement > 1) MVD1H=MVD1V=0;
  348.       MType = Decode(PredictedDHuff);
  349.       break;
  350.     case P_INTERPOLATED:
  351.       MType = Decode(InterpolatedDHuff);
  352.       break;
  353.     case P_DCINTRA:
  354.       if (!GetBit())
  355.     {
  356. #ifdef DEBUG
  357.       fprintf(stderr,"Expected one bit for DC Intra, 0 read.\n");
  358. #endif
  359.       fprintf(stderr,"Expected one bit for DC Intra, 0 read.\n");
  360.     }
  361.       break;
  362.     default:
  363. #ifdef DEBUG
  364.       fprintf(stderr,"Bad picture type.\n");
  365. #endif
  366.       fprintf(stderr,"Bad picture type.\n");
  367.       break;
  368.     }
  369.   if (QuantPMType[PType][MType]) MQuant=GetnBit(5);
  370.   if (MFPMType[PType][MType])
  371.     {
  372.       if (FullPelForward)
  373.     {
  374.       MVD1H = DecodeMV(ForwardIndex,MVD1H/2)<<1;
  375.       MVD1V = DecodeMV(ForwardIndex,MVD1V/2)<<1;
  376.     }
  377.       else
  378.     {
  379.       MVD1H = DecodeMV(ForwardIndex,MVD1H);
  380.       MVD1V = DecodeMV(ForwardIndex,MVD1V);
  381.     }
  382.     }
  383.   else if (PType==P_PREDICTED)
  384.     MVD1H=MVD1V=0;
  385.  
  386.   if (MBPMType[PType][MType])
  387.     {
  388.       if (FullPelBackward)
  389.     {
  390.       MVD2H = DecodeMV(BackwardIndex,MVD2H/2)<<1;
  391.       MVD2V = DecodeMV(BackwardIndex,MVD2V/2)<<1;
  392.     }
  393.       else
  394.     {
  395.       MVD2H = DecodeMV(BackwardIndex,MVD2H);
  396.       MVD2V = DecodeMV(BackwardIndex,MVD2V);
  397.     }
  398.     }
  399.   if (CBPPMType[PType][MType]) CBP = Decode(CBPDHuff);
  400.   else if (IPMType[PType][MType]) CBP=0x3f;
  401.   else CBP=0;
  402.   return(0);
  403. }
  404.  
  405.  
  406. static INT DecodeMV(INT fd,INT oldvect)
  407. {
  408.   INT r,v,limit;
  409.  
  410. #ifdef MV_DEBUG
  411.        fprintf(stderr,"DecodeMV\n");
  412.        getch();
  413. #endif
  414.  
  415.   limit = 1 << (fd+3);
  416.   v = Decode(MVDDHuff);
  417.   if (v)
  418.     {
  419.       if (v > 16) {v = v-33;}       /* our codes are positive, negative vals */
  420.                                     /* are greater than 16. */
  421.       fd--;                         /*Find out number of modulo bits=fd */
  422.       if (fd)
  423.     {
  424.       r = GetnBit(fd);            /* modulo lower bits */
  425.       if (v > 0) 
  426.         v = (((v-1)<<fd)|r)+1;  /* just "or" and add 1 for dead band. */
  427.       else
  428.         v = ((v+1)<<fd)+(-1^r); /* Needs mask to do an "or".*/
  429.     }
  430.       if (v==limit)
  431.     {
  432. #ifdef MV_DECODE
  433.       fprintf(stderr,"Warning: motion vector at positive limit.\n");
  434. #endif    
  435.         }
  436.     }
  437.   v += oldvect;                      /* DPCM */
  438.   if (v < -limit)
  439.     v += (limit << 1);
  440.   else if (v >= limit)
  441.     v -= (limit << 1);
  442.   if (v==limit)
  443.     {
  444. #ifdef MV_DEBUG
  445.         fprintf(stderr,"Apparently illegal reference: (MV %d) (LastMV %d).\n",v,oldvect);
  446. #endif
  447.     }
  448.   return(v);
  449. }
  450.